import type { NavigationGuardNext, RouteLocationNormalized, RouteRecordRaw } from "vue-router";
import NProgress from "@/utils/nprogress";
import { getToken } from "@/utils/auth";
import router from "@/router";
import { usePermissionStore, useUserStore } from "@/store";

export function setupPermission() {
  // whitelist router
  const whiteListNames = [
    "Login",
    "CustomerRegister",
    "CustomerRegisterActive",
    "ForgotPassword",
    "test00000",
    "bluetooth",
    "thankyou",
  ];

  router.beforeEach(async (to, from, next) => {
    NProgress.start();
    const isLogin = !!getToken(); // is loged?
    if (isLogin) {
      if (to.path === "/login") {
        // loged, redirect to home
        next({ path: "/" });
      } else {
        const permissionStore = usePermissionStore();
        // if routes loaded, check if the route is matched
        if (permissionStore.isRoutesLoaded) {
          if (to.matched.length === 0) {
            // route not matched, redirect to 404
            next("/404");
          } else {
            // dynamic set title
            const title = (to.params.title as string) || (to.query.title as string);
            if (title) {
              to.meta.title = title;
            }
            next();
          }
        } else {
          try {
            // generate dynamic routes
            const dynamicRoutes = await permissionStore.generateRoutes();
            dynamicRoutes.forEach((route: RouteRecordRaw) => router.addRoute(route));
            next({ ...to, replace: true });
          } catch (error) {
            console.error(error);
            // router error, clear user data and redirect to login
            await useUserStore().clearUserData();
            redirectToLogin(to, next);
            NProgress.done();
          }
        }
      }
    } else {
      console.log(to.name);
      if (whiteListNames.includes(to.name as string)) {
        next();
      } else {
        redirectToLogin(to, next);
        NProgress.done();
      }
    }
  });

  router.afterEach(() => {
    NProgress.done();
  });
}

function redirectToLogin(to: RouteLocationNormalized, next: NavigationGuardNext) {
  const params = new URLSearchParams(to.query as Record<string, string>);
  const queryString = params.toString();
  const redirect = queryString ? `${to.path}?${queryString}` : to.path;
  next(`/login?redirect=${encodeURIComponent(redirect)}`);
}

export function hasAuth(value: string | string[], type: "button" | "role" = "button") {
  const { roles, perms } = useUserStore().userInfo;
  /** 
  if (type === "button" && roles.includes("ROOT")) {
    return true;
  }
*/
  const auths = type === "button" ? perms : roles;
  return typeof value === "string"
    ? auths?.includes(value)
    : value.some((perm) => auths?.includes(perm));
}
